" ===
" 自动下载plug
" ===
"
let data_dir='~/.config/nvim'
if empty(glob(data_dir.'/autoload/plug.vim'))
  silent execute '!curl -fLo '.data_dir.'/autoload/plug.vim --create-dirs  https://raw.githubusercontent.com/junegunn/vim-plug/master/plug.vim'
  autocmd VimEnter * PlugInstall --sync | source $MYVIMRC
endif


" ===
" 基本配置
" ===
"
"" 行号
set number
set relativenumber
"" 光标
set cursorline
"" 换行相关
set wrap
set tw=0
set indentexpr=
""" 显示行尾空格
set list
set listchars=tab:▸\ ,trail:▫
"" 命令提示
set wildmenu
"" 关闭vi兼容
set nocompatible
"" 文件名相关
filetype on
filetype indent on
filetype plugin on
filetype plugin indent on
"" 字符编码
set encoding=utf-8
"" tab缩进
set expandtab
set tabstop=2
set shiftwidth=2
set softtabstop=2
"" 删除键处理
set backspace=indent,eol,start
"" 折叠相关
set foldmethod=indent
set foldlevel=99
"" 始终在当前行执行命令
set autochdir
"" 记住光标位置
au BufReadPost * if line("'\"") > 1 && line("'\"") <= line("$") | exe "normal! g'\"" | endif
"" 控制显示多少行时滚动
set scrolloff=5
"" 字符线
set cc=80
"" 允许未保存时跳转缓冲区
set hidden
"" 加快响应时间
set updatetime=100
"" 控制显示信息
set shortmess+=c


" ===
" 插件管理
" ===
"
call plug#begin(data_dir.'/plugged')
" ui
Plug 'vim-airline/vim-airline'
Plug 'vim-airline/vim-airline-themes'
Plug 'connorholyday/vim-snazzy'
" Undo Tree
Plug 'mbbill/undotree'
" Coc.nvim
Plug 'neoclide/coc.nvim', {'branch': 'release'}
" 高亮下划线
Plug 'RRethy/vim-illuminate'
" 显示颜色
Plug 'rrethy/vim-hexokinase', { 'do': 'make hexokinase' }
" 格式化工具
" Plug 'google/vim-maktaba'
" Plug 'google/vim-codefmt'
Plug 'sbdchd/neoformat'
" 任务配置插件
Plug 'skywind3000/asynctasks.vim'
Plug 'skywind3000/asyncrun.vim'
" 搜索插件
Plug 'junegunn/fzf', { 'do': { -> fzf#install() } }
Plug 'junegunn/fzf.vim'
" Git
Plug 'tpope/vim-fugitive'
Plug 'airblade/vim-gitgutter'
" 符号成对
Plug 'jiangmiao/auto-pairs'
" 代码大纲
"Plug 'liuchengxu/vista.vim'
Plug 'preservim/tagbar'
" 缩进线
Plug 'yggdroot/indentline'
" 显示按键功能
Plug 'liuchengxu/vim-which-key'
" 代码片段
Plug 'honza/vim-snippets'
" 第一屏
Plug 'mhinz/vim-startify'
" 注释
Plug 'preservim/nerdcommenter'
" jsonc
Plug 'neoclide/jsonc.vim'
call plug#end()


" ===
" 按键映射
" ===
"
"" which-key
let g:which_key_map={}
let g:mapleader="\<Space>"
set timeoutlen=500
call which_key#register('<Space>', "g:which_key_map")
nnoremap <silent> <leader> :WhichKey '<Space>'<CR>
"" 其他配置
inoremap jk <ESC>
noremap <silent> <leader><CR> :nohlsearch<CR>
noremap <silent> <leader><up> :res +5<CR>
noremap <silent> <leader><down> :res -5<CR>
noremap <silent> <leader><right> :vertical resize+5<CR>
noremap <silent> <leader><left> :vertical resize-5<CR>
nmap <silent> <leader>; <Plug>NERDCommenterToggle
xmap <silent> <leader>; <Plug>NERDCommenterMinimal
nmap <silent> <leader>: <Plug>NERDCommenterUncomment
xmap <silent> <leader>: <Plug>NERDCommenterUncomment
"" 窗口相关
noremap <silent> <leader>ws :split<CR>
noremap <silent> <leader>wv :vsplit<CR>
noremap <silent> <leader>wo :on<CR>
noremap <silent> <leader>wtv <C-w>t<C-w>H
noremap <silent> <leader>wts <C-w>t<C-w>K
let g:which_key_map['w']={
  \ 'name': '窗口相关',
  \ 's': '水平分割窗口',
  \ 'v': '垂直分割窗口',
  \ 'o': '关闭其他窗口',
  \ 't': {
  \   'name': '水平与垂直切换',
  \   's': '切换至水平窗口',
  \   'v': '切换至垂直窗口',
  \   },
  \ }
"" tab相关
noremap <silent> <leader>tu :tabe<CR>
noremap <silent> <leader>tn :tabn<CR>
noremap <silent> <leader>tp :tabp<CR>
noremap <silent> <leader>to :tabo<CR>
let g:which_key_map['t']={
  \ 'name': 'tab相关',
  \ 'u': '新建tab',
  \ 'n': '下一个tab',
  \ 'p': '上一个tab',
  \ 'o': '关闭其他tab',
  \ }
"" 文件相关
noremap <silent> <leader>fs :w<CR>
noremap <silent> <leader>ff :Neoformat<CR>
noremap <silent> <leader>fl :CocCommand explorer<CR>
noremap <silent> <leader>fR :source $MYVIMRC<CR>
noremap <silent> <leader>fed :e $MYVIMRC<CR>
let g:which_key_map['f']={
  \ 'name': '文件相关',
  \ 's': '保存当前文件',
  \ 'f': '格式化当前文件',
  \ 'l': '文件管理器',
  \ 'R': '刷新vimrc',
  \ 'e': {'name':'配置文件','d':'打开配置文件'},
  \ }
"" buffer相关
nmap <silent> <leader>br <Plug>(coc-rename)
nnoremap <silent> <leader>bb :Buffers<CR>
nnoremap <silent> <leader>bn :bn<cr>
nnoremap <silent> <leader>bp :bp<cr>
nnoremap <silent> <leader>bd :bd<cr>
"关闭其他缓冲区 
nnoremap <silent> <leader>bo :%bd<bar>e#<bar>bd#<bar>'"<cr>
" %bd=删除所有缓冲区
" e#=打开最后一个缓冲区进行编辑
" bd#=删除使用时创建的[无名称]缓冲区
" '"=保持光标位置
let g:which_key_map['b']={
  \ 'name': 'buffer相关',
  \ 'r': '当前buffer内重命名',
  \ 'b': 'buffer搜索',
  \ 'n': '下一个buffer',
  \ 'p': '上一个buffer',
  \ 'd': '退出当前buffer',
  \ 'o': '关闭其他buffer',
  \ }
"" 退出相关
noremap <silent> <leader>qq :q<CR>
noremap <silent> <leader>qa :wqa<CR>
let g:which_key_map['q']={
  \ 'name': '退出相关',
  \ 'q': '退出当前文件',
  \ 'a': '退出并保存所有文件',
  \ }
"" 撤销相关
nnoremap <silent> <leader>uu :UndotreeToggle<CR>
let g:which_key_map['u']={
  \ 'name': '撤销相关',
  \ 'u': '修改历史列表',
  \ }
"" 搜索相关
nnoremap <silent> <leader>sc :set spell!<CR>
nnoremap <silent> <leader>sl :Lines<CR>
nnoremap <silent> <leader>sf :Files<CR>
let g:which_key_map['s']={
  \ 'name': '搜索相关',
  \ 'l': '搜索行',
  \ 'f': '搜索文件',
  \ }
"" 代码额外操作
xmap <silent> <leader>aa  <Plug>(coc-codeaction-selected)
nmap <silent> <leader>aa  <Plug>(coc-codeaction-selected)
noremap <silent> <leader>as :Startify<CR>
let g:which_key_map['a']={
  \ 'name': '额外操作相关',
  \ 'a': '代码额外操作',
  \ 's': '打开起始页',
  \ }
"" 代码任务
nnoremap <silent> <leader>rl :CocList tasks<CR>
let g:which_key_map['r']={
  \ 'name': '代码任务',
  \ 'l': '代码任务列表',
  \ }
"" 错误相关
nmap <silent> <leader>ep <Plug>(coc-diagnostic-prev)
nmap <silent> <leader>en <Plug>(coc-diagnostic-next)
let g:which_key_map['e']={
  \ 'name': '错误相关',
  \ 'n': '下一个错误',
  \ 'p': '上一个错误',
  \ }
"" 代码相关
noremap <silent> <leader>cl :TagbarToggle<CR>
let g:which_key_map['c']={
  \ 'name': '代码相关',
  \ 'l': '代码大纲',
  \ }
"" git相关
nmap <silent> <leader>gj <Plug>(GitGutterNextHunk)
nmap <silent> <leader>gk <Plug>(GitGutterPrevHunk)
nmap <silent> <leader>gs <Plug>(GitGutterStageHunk)
nmap <silent> <leader>gu <Plug>(GitGutterUndoHunk)
nmap <silent> <leader>gp <Plug>(GitGutterPreviewHunk)
let g:which_key_map['g']={
  \ 'name': 'Git相关',
  \ 'j': '下一个更改块',
  \ 'k': '上一个更改块',
  \ 's': '暂存更改',
  \ 'u': '取消更改',
  \ 'p': '预览更改块',
  \ }
"" 代码定义相关
nmap <silent> <leader>hd <Plug>(coc-definition)
nmap <silent> <leader>hy <Plug>(coc-type-definition)
nmap <silent> <leader>hi <Plug>(coc-implementation)
nmap <silent> <leader>hr <Plug>(coc-references)
""" 查看文档
nnoremap <silent> <leader>hv :call <SID>show_documentation()<CR>
function! s:show_documentation()
  if (index(['vim','help'], &filetype) >= 0)
    execute 'h '.expand('<cword>')
  elseif (coc#rpc#ready())
    call CocActionAsync('doHover')
  else
    execute '!' . &keywordprg . " " . expand('<cword>')
  endif
endfunction
let g:which_key_map['h']={
  \ 'name': '代码定义相关',
  \ 'd': '跳转当前代码定义',
  \ 'y': '跳转当前代码类型定义',
  \ 'i': '跳转当前代码实现',
  \ 'r': '跳转当前代码引用',
  \ 'v': '查看当前变量文档(vim)',
  \ }
"" 翻译
nmap <leader>oy <Plug>(coc-translator-p)
vmap <leader>oy <Plug>(coc-translator-pv)
nmap <leader>oi <Plug>(coc-translator-r)
vmap <leader>oi <Plug>(coc-translator-rv)
let g:which_key_map['o']={
  \ 'name': '翻译相关',
  \ 'y': '翻译当前单词',
  \ 'i': '翻译并插入当前单词',
  \ }


" ===
" UI
" ===
"
if (empty($TMUX))
  if (has("nvim"))
    let $NVIM_TUI_ENABLE_TRUE_COLOR=1
  endif
  if (has("termguicolors"))
    set termguicolors
  endif
endif
syntax on
set smartcase
set hlsearch
set incsearch
set ignorecase
colorscheme snazzy
"" 状态栏始终显示
set laststatus=2
"" 标志栏始终显示
set signcolumn=yes


" ===
" 插件配置
" ===
"
"" coc.nvim
let g:coc_global_extensions = [
	\ 'coc-emmet',
	\ 'coc-css',
	\ 'coc-html',
	\ 'coc-tsserver',
	\ 'coc-json',
  \ 'coc-vetur',
	\ 'coc-python',
	\ 'coc-translator',
	\ 'coc-java',
	\ 'coc-clangd',
	\ 'coc-actions',
	\ 'coc-tasks',
	\ 'coc-explorer',
	\ 'coc-snippets',
  \ 'coc-marketplace']
""" 使用回车确认补全代码片段
inoremap <silent><expr> <cr> pumvisible() ? "\<C-y>" : "\<CR>"
""" 主动触发补全
if has('nvim')
  inoremap <silent><expr> <c-n> coc#refresh()
else
  inoremap <silent><expr> <c-n> coc#refresh()
endif
let g:snips_author="zoneaurora"

"" vim-illuminate
let g:Illuminate_delay = 0
augroup illuminate_augroup
    autocmd!
    autocmd VimEnter * hi illuminatedWord cterm=underline gui=underline
augroup END

" asynctasks.vim
let g:asyncrun_open = 6

"indentline
let g:indentLine_char_list = ['|', '¦', '┆', '┊']
" let g:indentLine_color_term = 238
" let g:indentLine_color_gui = '#333333'

" gitgutter
"" 生效范围
let g:gitgutter_max_signs = 500
"" 关闭默认的映射
let g:gitgutter_map_keys=0
"" 使用浮动窗口进行预览
let g:gitgutter_preview_win_floating=1

" asynctasks
let g:asyncrun_rootmarks = ['.git', '.svn', '.root']

" airline
let g:airline_symbols={}
let g:airline#extensions#tabline#enabled = 1
let g:airline_theme="molokai"
let g:airline_left_sep = ''
let g:airline_left_alt_sep = ''
let g:airline_right_sep = ''
let g:airline_right_alt_sep = ''
let g:airline_symbols.branch = ''
let g:airline_symbols.colnr = ' :'
let g:airline_symbols.readonly = ''
let g:airline_symbols.linenr = ' :'
let g:airline_symbols.maxlinenr = '☰ '
let g:airline_symbols.dirty='⚡'
let g:airline#extensions#whitespace#enabled=0

" NERDComment
let g:NERDCreateDefaultMappings=0
let g:NERDSpaceDelims=1
let g:NERDCompactSexyComs=1

" json to jsonc
augroup JsonToJsonc
  autocmd! FileType json set filetype=jsonc
augroup END

" Format
let g:neoformat_jsonc_prettier={
  \ 'exe': 'prettier',
  \ 'args': ['--stdin-filepath', '"%:p"', '--parser', 'json'],
  \ 'stdin': 0,
  \ }

let g:neoformat_enabled_jsonc=['prettier']
